package com.onluy.frameworkcloud.batis.tools.util;


import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.onluy.frameworkcloud.data.annotation.Table;
import com.onluy.frameworkcloud.data.entity.BaseEntity;
import com.onluy.frameworkcloud.data.entity.Entity;
import com.onluy.frameworkcloud.data.entity.EntityHelper;
import com.onluy.frameworkcloud.data.entity.OperColumn;
import com.onluy.frameworkcloud.data.entity.OperColumnHelper;
import com.onluy.frameworkcloud.data.exception.EmptyEntityException;
import com.onluy.frameworkcloud.data.exception.NoColumnException;
import com.onluy.frameworkcloud.data.exception.NotEntityException;

public abstract class EntityUtil
{
    protected static final Logger log = LoggerFactory.getLogger(EntityUtil.class);

    public static Class<?> findEntity(Class<?> clazz)
    {
        if (clazz.getAnnotation(Table.class) != null) {
            return clazz;
        }
        Class superClazz = clazz.getSuperclass();
        if (Object.class.equals(superClazz)) {
            throw new NotEntityException(clazz);
        }
        return findEntity(superClazz);
    }

    public static void assertExistField(Object object, String field)
    {
        Class entityClazz = findEntity(object.getClass());
        try {
            entityClazz.getDeclaredField(field);
        } catch (NoSuchFieldException e) {
            throw new NoColumnException(((Table)entityClazz.getAnnotation(Table.class)).name(), field);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public static Map<String, Field> getAllColumnFields(Class<?> clazz)
    {
        return EntityHelper.getAllColumnFields(clazz);
    }

    public static Map<String, Object> getAllValuesByColumn(Entity entity)
    {
        Map values = new HashMap();
        MetaObject entityMeta = SystemMetaObject.forObject(entity);
        Map fields = getAllColumnFields(entity.getClass());
        for (Object column : fields.keySet()) {
            values.put(column, entityMeta.getValue(((Field)fields.get(column.toString())).getName()));
        }
        return values;
    }

    public static void handleOperColumn(BaseEntity entity, String[] conditionColumns)
    {
        if ((conditionColumns != null) && (conditionColumns.length > 0)) {
            Map operColumns = EntityHelper.operColumns(entity);
            if ((operColumns == null) || (operColumns.keySet().size() == 0)) {
                throw new EmptyEntityException();
            }

            for (Object column : operColumns.keySet()) {
                OperColumn operColumn = (OperColumn)operColumns.get(column.toString());
                if (OperColumnHelper.isCondition(operColumn)) {
                    OperColumnHelper.cancelCondition(operColumn);
                }

            }

            MetaObject entityMeta = SystemMetaObject.forObject(entity);
            Map fields = getAllColumnFields(entity.getClass());
            for (String column : conditionColumns) {
                Field field = (Field)fields.get(column);
                if (field == null) {
                    throw new NoColumnException(((Table)entity.getClass().getAnnotation(Table.class)).name(), column);
                }
                String property = field.getName();
                Object value = entityMeta.getValue(property);
                Class type = field.getType();
                OperColumn operColumn = (OperColumn)operColumns.get(column);
                if (operColumn == null)
                    operColumns.put(column, new OperColumn(column, property, value, type).asCondition());
                else
                    operColumn.asCondition();
            }
        }
    }
}